//Heap_memory_management_helper.c
#define HEAP_MEMORY_MANAGEMENT_HELPER_C
#include "Heap_memory_management_helper.h"

static Manager* MANAGER_INSTANCE = NULL;

static void add_matrix_to_manager(Matrix* m);
static void add_float_matrix_to_manager(Matrix_float* m);
static void add_double_matrix_to_manager(Matrix_double* m);

const void clear_matrix(Matrix* m);
const void clear_float_matrix(Matrix_float* mf);
const void clear_double_matrix(Matrix_double* md);

// 初始化管理器 (单例模式只存在一个管理器)
Manager *manager_instance(void){
    if (MANAGER_INSTANCE == NULL) {
        MANAGER_INSTANCE = (Manager*)malloc(sizeof(Manager));
        if (MANAGER_INSTANCE == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        MANAGER_INSTANCE->max_num = MAX_NUM;  // 初始最大值
        MANAGER_INSTANCE->max_num_float = MAX_NUM / 2;
        MANAGER_INSTANCE->max_num_double = MAX_NUM / 2;
        MANAGER_INSTANCE->matrixs = (Matrix**)malloc(MANAGER_INSTANCE->max_num * sizeof(Matrix*));
        MANAGER_INSTANCE->matrixs_float = (Matrix_float**)malloc(MANAGER_INSTANCE->max_num_float * sizeof(Matrix_float*));
        MANAGER_INSTANCE->matrixs_double = (Matrix_double**)malloc(MANAGER_INSTANCE->max_num_double * sizeof(Matrix_double*));

        if (MANAGER_INSTANCE->matrixs == NULL || MANAGER_INSTANCE->matrixs_float == NULL || MANAGER_INSTANCE->matrixs_double == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            free(MANAGER_INSTANCE);
            exit(1);
        }

        MANAGER_INSTANCE->num = 0;
        MANAGER_INSTANCE->num_float = 0;
        MANAGER_INSTANCE->num_double = 0;
        MANAGER_INSTANCE->all_num = 0;
    }
    return MANAGER_INSTANCE;
}

// 增加矩阵到管理器
static void add_matrix_to_manager(Matrix* m) {
    if (m == NULL) {
        fprintf(stderr, "Matrix is NULL\n");
        return; //NULL
    }

    Manager* manager = manager_instance();
    if (manager->num >= manager->max_num) {
        // 增加 max_num
        // 可以根据需要调整增长策略
        manager->max_num = manager->max_num < 32 ? (manager->max_num = manager->max_num * 2 - manager->max_num/2) : (manager->max_num *= 2); 
        
        Matrix** new_matrixs = (Matrix**)realloc(manager->matrixs, manager->max_num * sizeof(Matrix*));  // 修改: Matrix* -> Matrix**
        if (new_matrixs == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        manager->matrixs = new_matrixs;
    }


    // 检查矩阵是否已经存在
    for(int i = 0; i < manager->num; i++){
        if(manager->matrixs[i] == m){
            return;
        }
    }
    
    manager->matrixs[manager->num++] = m;
    manager->all_num++;
    
}

// 增加矩阵到管理器
static void add_float_matrix_to_manager(Matrix_float* m) {
    if (m == NULL) {
        fprintf(stderr, "Matrix is NULL\n");
        return; //NULL
    }

    Manager* manager = manager_instance();
    if (manager->num_float >= manager->max_num_float) {
        // 增加 max_num
        // 可以根据需要调整增长策略
        manager->max_num_float = manager->max_num_float < 32 ? (manager->max_num_float = manager->max_num_float * 2 - manager->max_num_float/2) : (manager->max_num_float *= 2); 
        
        Matrix_float** new_matrixs = (Matrix_float**)realloc(manager->matrixs_float, manager->max_num_float * sizeof(Matrix_float*));  // 修改: Matrix* -> Matrix**
        if (new_matrixs == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        manager->matrixs_float = new_matrixs;
    }


    // 检查矩阵是否已经存在
    for(int i = 0; i < manager->num_float; i++){
        if(manager->matrixs_float[i] == m){
            return;
        }
    }
    
    manager->matrixs_float[manager->num_float++] = m;
    manager->all_num++;
}

static void add_double_matrix_to_manager(Matrix_double* m) {
    if (m == NULL) {
        fprintf(stderr, "Matrix is NULL\n");
        return; //NULL
    }

    Manager* manager = manager_instance();
    if (manager->num_double >= manager->max_num_double) {
        // 增加 max_num
        // 可以根据需要调整增长策略
        manager->max_num_double = manager->max_num_double < 32 ? (manager->max_num_double = manager->max_num_double * 2 - manager->max_num_double/2) : (manager->max_num_double *= 2); 
        
        Matrix_double** new_matrixs = (Matrix_double**)realloc(manager->matrixs_double, manager->max_num_double * sizeof(Matrix_double*));  // 修改: Matrix* -> Matrix**
        if (new_matrixs == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            exit(1);
        }
        manager->matrixs_double = new_matrixs;
    }


    // 检查矩阵是否已经存在
    for(int i = 0; i < manager->num_double; i++){
        if(manager->matrixs_double[i] == m){
            return;
        }
    }
    
    manager->matrixs_double[manager->num_double++] = m;
    manager->all_num++;
}



/**
  * @brief  create a rows by columns matrix (a two-dimensional int array) with zero initialized memory.
  * @param  (int rows, int cols)
  *  
  * Rows and columns of a matrix
  * @retval struct Matrix*
  */
Matrix *create_matrix(unsigned int rows, unsigned int cols) {
    Matrix *m = (Matrix *)malloc(sizeof(Matrix));
    if (m == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    m->rows = rows;
    m->cols = cols;
    m->data = (int **)malloc(rows * sizeof(int *));
    if (m->data == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        free(m);
        exit(1);
    }
    for (int i = 0; i < rows; i++) {
        m->data[i] = (int *)malloc(cols * sizeof(int));
        if (m->data[i] == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            for (int j = 0; j < i; j++) {
                free(m->data[j]);
            }
            free(m->data);
            free(m);
            exit(1);
        } else {
            //The matrix is initialized to zero
            for (int j = 0; j < cols; j++) {
                m->data[i][j] = 0;
            }
        }
    }
    add_matrix_to_manager(m);
    return m;
}

// 创建浮点矩阵
Matrix_float *create_float_matrix(unsigned int rows, unsigned int cols) {
    Matrix_float *mf = (Matrix_float*)malloc(sizeof(Matrix_float));
    if (mf == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    mf->rows = rows;
    mf->cols = cols;
    mf->data = (float**)malloc(rows * sizeof(float*));
    if (mf->data == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        free(mf);
        exit(1);
    }
    for (int i = 0; i < rows; i++) {
        mf->data[i] = (float*)malloc(cols * sizeof(float));
        if (mf->data[i] == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            for (int j = 0; j < i; j++) {
                free(mf->data[j]);
            }
            free(mf->data);
            free(mf);
            exit(1);
        } else {
            //The matrix is initialized to zero
            for (int j = 0; j < cols; j++) {
                mf->data[i][j] = 0;
            }
        }
    }
    add_float_matrix_to_manager(mf);
    return mf;
}

// 创建双精度矩阵
Matrix_double *create_double_matrix(unsigned int rows, unsigned int cols) {
    Matrix_double *md = (Matrix_double*)malloc(sizeof(Matrix_double));
    if (md == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }
    md->rows = rows;
    md->cols = cols;
    md->data = (double**)malloc(rows * sizeof(double*));
    if (md->data == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        free(md);
        exit(1);
    }
    for (int i = 0; i < rows; i++) {
        md->data[i] = (double*)malloc(cols * sizeof(double));
        if (md->data[i] == NULL) {
            fprintf(stderr, "Memory allocation failed\n");
            for (int j = 0; j < i; j++) {
                free(md->data[j]);
            }
            free(md->data);
            free(md);
            exit(1);
        }else {
            //The matrix is initialized to zero
            for (int j = 0; j < cols; j++) {
                md->data[i][j] = 0;
            }
        }
    }
    add_double_matrix_to_manager(md);
    return md;
}


// 设置矩阵的值从字符串
void set_matrix(Matrix* m, const char* str) {
    /*strdup 函数用于复制一个字符串。
    它会在堆上分配足够的内存来存储源字符串及其终止的空字符 \0，*/
    char* str_copy = strdup(str);
    if (str_copy == NULL) {
        fprintf(stderr, "Memory allocation failed\n");
        exit(1);
    }

    const char *delim = " ,\t\n";
    /*strtok 函数用于将字符串分割成一系列子字符串（标记）。
    它会根据指定的分隔符 delim 将字符串 str 分割成多个部分。*/
    char* token = strtok(str_copy, delim);
    unsigned int count = 0;

    while (token != NULL && count < m->rows * m->cols) {
        /*atoi 函数将字符串 str 转换为整数。
        它会跳过字符串开头的空白字符，然后读取数字字符并将其转换为整数，
        直到遇到非数字字符为止。*/
        m->data[count / m->cols][count % m->cols] = atoi(token);
        token = strtok(NULL, delim);
        count++;
    }

    if (count != m->rows * m->cols) {
        fprintf(stderr, "Number of elements in string does not match matrix dimensions\n");
        free(str_copy);
        exit(1);
    }

    free(str_copy);
}



#ifdef __MANAGEMENT_VLA

// 复制二维数组到矩阵
void copy_array_to_matrix(Matrix* m,unsigned int rows,unsigned int cols, int array[rows][cols]) {
    if (m->rows != rows || m->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }

    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            m->data[i][j] = array[i][j];
        }
    }
}

void copy_array_to_float_matrix(Matrix_float* mf,unsigned int rows,unsigned int cols, float array[rows][cols]) {
    if (mf->rows != rows || mf->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            mf->data[i][j] = array[i][j];
        }
    }
}

void copy_array_to_double_matrix(Matrix_double* md,unsigned int rows,unsigned int cols, double array[rows][cols]) {
    if (md->rows != rows || md->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            md->data[i][j] = array[i][j];
        }
    }
}

#else
/*If compile C++*/
void copy_array_to_matrix(Matrix* m,unsigned int rows,unsigned int cols, int **array) {
    if (m->rows != rows || m->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }

    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            m->data[i][j] = array[i][j];
        }
    }
}

void copy_array_to_float_matrix(Matrix_float* mf,unsigned int rows,unsigned int cols, float **array) {
    if (mf->rows != rows || mf->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            mf->data[i][j] = array[i][j];
        }
    }
}

void copy_array_to_double_matrix(Matrix_double* md,unsigned int rows,unsigned int cols, double **array) {
    if (md->rows != rows || md->cols != cols) {
        fprintf(stderr, "Matrix dimensions do not match array dimensions\n");
        exit(1);
    }
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            md->data[i][j] = array[i][j];
        }
    }
}

#endif




/**
  * @brief  计算矩阵的行列式
  * 使用递归方法计算矩阵的行列式
  * @param  matrix 输入的方阵
  * @retval 行列式的值
  */
double determinant(Matrix* A) {
    if (A->rows != A->cols) {
        fprintf(stderr, "Matrix is not square\n");
        exit(1);
    }

    int n = A->rows;
    if (n == 1) {
        return A->data[0][0];
    }

    double det = 0;
    double sign = 1;
    Matrix* submatrix = create_matrix(n - 1, n - 1);

    for (int f = 0; f < n; f++) {
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == f) {
                    continue;
                }
                submatrix->data[subi][subj] = A->data[i][j];
                subj++;
            }
            subi++;
        }
        det += sign * A->data[0][f] * determinant(submatrix);
        sign = -sign;
    }

    manager_delete_matrix(submatrix);
    return det;
}

// 计算矩阵的行列式 (double 类型)
double determinant_double(Matrix_double* A) {
    if (A->rows != A->cols) {
        fprintf(stderr, "Matrix is not square\n");
        exit(1);
    }

    int n = A->rows;
    if (n == 1) {
        return A->data[0][0];
    }

    double det = 0;
    double sign = 1;
    Matrix_double* submatrix = create_double_matrix(n - 1, n - 1);

    for (int f = 0; f < n; f++) {
        int subi = 0;
        for (int i = 1; i < n; i++) {
            int subj = 0;
            for (int j = 0; j < n; j++) {
                if (j == f) {
                    continue;
                }
                submatrix->data[subi][subj] = A->data[i][j];
                subj++;
            }
            subi++;
        }
        det += sign * A->data[0][f] * determinant_double(submatrix);
        sign = -sign;
    }

    manager_delete_matrix_double(submatrix);
    return det;
}

// 计算矩阵的代数余子式
Matrix* matrix_cofactor(Matrix* A, int p, int q) {
    int n = A->rows;
    Matrix* cofactor = create_matrix(n - 1, n - 1);

    int i = 0, j = 0;
    for (int row = 0; row < n; row++) {
        for (int col = 0; col < n; col++) {
            if (row != p && col != q) {
                cofactor->data[i][j++] = A->data[row][col];
                if (j == n - 1) {
                    j = 0;
                    i++;
                }
            }
        }
    }

    return cofactor;
}

// 计算矩阵的伴随矩阵
Matrix* matrix_adjoint(Matrix* A) {
    int n = A->rows;
    Matrix* adjoint = create_matrix(n, n);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            Matrix* cofactor = matrix_cofactor(A, i, j);
            int sign = ((i + j) % 2 == 0) ? 1 : -1;
            adjoint->data[j][i] = sign * determinant(cofactor);
            manager_delete_matrix(cofactor);
        }
    }

    return adjoint;
}

// 计算矩阵的代数余子式 (double 类型)
Matrix_double* matrix_cofactor_double(Matrix* A, int p, int q) {
    int n = A->rows;
    Matrix_double* cofactor = create_double_matrix(n - 1, n - 1);

    int i = 0, j = 0;
    for (int row = 0; row < n; row++) {
        for (int col = 0; col < n; col++) {
            if (row != p && col != q) {
                cofactor->data[i][j++] = (double)A->data[row][col];
                if (j == n - 1) {
                    j = 0;
                    i++;
                }
            }
        }
    }

    return cofactor;
}

// 计算矩阵的伴随矩阵 (double 类型)
Matrix_double* matrix_adjoint_double(Matrix* A) {
    int n = A->rows;
    Matrix_double* adjoint = create_double_matrix(n, n);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            Matrix_double* cofactor = matrix_cofactor_double(A, i, j);
            int sign = ((i + j) % 2 == 0) ? 1 : -1;
            adjoint->data[j][i] = sign * determinant_double(cofactor);
            manager_delete_matrix_double(cofactor);
        }
    }

    return adjoint;
}

// 求矩阵的逆 (公式法)
Matrix_double* matrix_inverse(Matrix *A) {
    if (A->rows != A->cols) {
        fprintf(stderr, "Matrix is not square\n");
        exit(1);
    }

    double det = determinant(A);
    if (det == 0) {
        fprintf(stderr, "Matrix not invertible\n");
        return NULL;
    }

    int n = A->rows;
    Matrix_double* inverse = create_double_matrix(n, n);

    Matrix_double* adjoint = matrix_adjoint_double(A);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            inverse->data[i][j] = adjoint->data[i][j] / det;
        }
    }

    manager_delete_matrix_double(adjoint);

    return inverse;
}

/**
  * @brief  使用幂迭代法求特征值和特征向量
  * 步骤 1: 初始化
        选择一个初始向量 V_0 （通常为一个随机向量，且为单位向量,防止数值溢出)
        设定迭代次数k或收敛阈值ϵ。
  * 步骤 2: 迭代过程
        检查矩阵是否为方阵，如果不是则报错退出。
        初始化两个向量 b 和 b_new，并进行幂迭代法计算特征向量。
        迭代1000次，每次更新 b_new 并归一化。
        将最终的特征向量存入 eigenvectors。
        计算特征值并存入 eigenvalues。
  * 步骤 3: 输出结果
  * @param  matrix 输入的方阵
  * @param  matrix_size 矩阵的大小（假设为n*n）
  * @param  eigenvectors 存储特征向量的数组
  * @param  eigenvalues 存储特征值的数组
  * @param  num_eigenvalues 需要计算的特征值的数量
  * @retval 无
  */
void matrix_eigen(Matrix* A, double* eigenvalues, double* eigenvectors) {
    if (A->rows != A->cols) {
        fprintf(stderr, "Matrix is not square\n");
        exit(1);
    }

    int n = A->rows;
    double* b = (double*)malloc(n * sizeof(double));
    double* b_new = (double*)malloc(n * sizeof(double));
    double norm;

    // 步骤 1: 初始化
    // 选择一个初始向量 V_0 （通常为一个随机向量，且为单位向量,防止数值溢出)
    for (int i = 0; i < n; i++) {
        b[i] = 1.0 / n; // 初始化为单位向量
    }

    // 步骤 2: 迭代过程
    // 迭代1000次，每次更新 b_new 并归一化。
    for (int i = 0; i < 1000; i++) { // 迭代次数
        for (int j = 0; j < n; j++) {
            b_new[j] = 0;
            for (int k = 0; k < n; k++) {
                b_new[j] += A->data[j][k] * b[k];
            }
        }

        // 归一化 b_new
        norm = 0;
        for (int j = 0; j < n; j++) {
            norm += b_new[j] * b_new[j];
        }
        norm = sqrt(norm);

        for (int j = 0; j < n; j++) {
            b_new[j] /= norm;
        }

        // 交换 b 和 b_new
        double* temp = b;
        b = b_new;
        b_new = temp;
    }

    // 步骤 3: 输出结果
    // 将最终的特征向量存入 eigenvectors。
    for (int i = 0; i < n; i++) {
        eigenvectors[i] = b[i];
    }

    // 计算特征值
    // 特征值可以通过 Rayleigh 商来估计
    double eigenvalue = 0;
    for (int i = 0; i < n; i++) {
        eigenvalue += A->data[i][i] * eigenvectors[i];
    }

    eigenvalues[0] = eigenvalue;

    free(b);
    free(b_new);
}


// Destroy a matrix (just free the matrix data,the matrix is not freed)
const void clear_matrix(Matrix* m) {
    for (int i = 0; i < m->rows; i++) {
        free(m->data[i]);
    }
    free(m->data);
    m->data = NULL;
    m->rows = 0;
    m->cols = 0;
}

const void clear_float_matrix(Matrix_float* mf) {
    for (int i = 0; i < mf->rows; i++) {
        free(mf->data[i]);
    }
    free(mf->data);
    mf->data = NULL;
    mf->rows = 0;
    mf->cols = 0;
}

const void clear_double_matrix(Matrix_double* md) {
    for (int i = 0; i < md->rows; i++) {
        free(md->data[i]);
    }
    free(md->data);
    md->data = NULL;
    md->rows = 0;
    md->cols = 0;
}

// 计算两个二维矩阵的乘积 (内积)
Matrix* matrix_multiply(Matrix* A, Matrix* B) {
    if (A->cols != B->rows) {
        fprintf(stderr, "Matrix dimensions do not match for multiplication\n");
        exit(1);
    }

    Matrix* result = create_matrix(A->rows, B->cols);
    for (unsigned int i = 0; i < A->rows; i++) {
        for (unsigned int j = 0; j < B->cols; j++) {
            result->data[i][j] = 0;
            for (unsigned int k = 0; k < A->cols; k++) {
                result->data[i][j] += A->data[i][k] * B->data[k][j];
            }
        }
    }
    return result;
}

// 计算两个二维矩阵的乘积 (内积) (double 类型)
Matrix_double* matrix_multiply_double(Matrix_double* A, Matrix_double* B) {
    if (A->cols != B->rows) {
        fprintf(stderr, "Matrix dimensions do not match for multiplication\n");
        exit(1);
    }

    int rows_A = A->rows;
    int cols_A = A->cols;
    int cols_B = B->cols;

    Matrix_double* result = create_double_matrix(rows_A, cols_B);
    for (unsigned int i = 0; i < rows_A; i++) {
        for (unsigned int j = 0; j < cols_B; j++) {
            result->data[i][j] = 0;
            for (unsigned int k = 0; k < cols_A; k++) {
                result->data[i][j] += A->data[i][k] * B->data[k][j];
            }
        }
    }
    return result;
}

// 矩阵加法函数实现 (double 类型)
Matrix_double* matrix_add_double(Matrix_double* A, Matrix_double* B) {
    if (A->rows != B->rows || A->cols != B->cols) {
        fprintf(stderr, "Matrix dimensions do not match for addition\n");
        exit(1);
    }

    int rows = A->rows;
    int cols = A->cols;

    Matrix_double* result = create_double_matrix(rows, cols);
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            result->data[i][j] = A->data[i][j] + B->data[i][j];
        }
    }
    return result;
}



// 矩阵加法函数实现
Matrix* matrix_add(Matrix* A, Matrix* B) {
    if (A->rows != B->rows || A->cols != B->cols) {
        fprintf(stderr, "Matrix dimensions do not match for addition\n");
        exit(1);
    }

    Matrix* result = create_matrix(A->rows, A->cols);
    for (unsigned int i = 0; i < A->rows; i++) {
        for (unsigned int j = 0; j < A->cols; j++) {
            result->data[i][j] = A->data[i][j] + B->data[i][j];
        }
    }
    return result;
}

// 矩阵减法函数实现
Matrix* matrix_sub(Matrix* A, Matrix* B) {
    if (A->rows != B->rows || A->cols != B->cols) {
        fprintf(stderr, "Matrix dimensions do not match for addition\n");
        exit(1);
    }

    Matrix* result = create_matrix(A->rows, A->cols);
    for (unsigned int i = 0; i < A->rows; i++) {
        for (unsigned int j = 0; j < A->cols; j++) {
            result->data[i][j] = A->data[i][j] - B->data[i][j];
        }
    }
    return result;
}


// 矩阵减法函数实现 (double 类型)
Matrix_double* matrix_sub_double(Matrix_double* A, Matrix_double* B) {
    if (A->rows != B->rows || A->cols != B->cols) {
        fprintf(stderr, "Matrix dimensions do not match for subtraction\n");
        exit(1);
    }

    int rows = A->rows;
    int cols = A->cols;

    Matrix_double* result = create_double_matrix(rows, cols);
    for (unsigned int i = 0; i < rows; i++) {
        for (unsigned int j = 0; j < cols; j++) {
            result->data[i][j] = A->data[i][j] - B->data[i][j];
        }
    }
    return result;
}

void show_matrix(Matrix* m) {
    if(m ->cols==0 || m->rows==0) return;
    for (int i = 0; i < m->rows; i++) {
        for (int j = 0; j < m->cols; j++) {
            printf("%d ", m->data[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

// 显示浮点矩阵
void show_float_matrix(Matrix_float* mf) {
    if(mf ->cols==0 || mf->rows==0) return;
    for (int i = 0; i < mf->rows; i++) {
        for (int j = 0; j < mf->cols; j++) {
            printf("%f ", mf->data[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

// 显示双精度矩阵
void show_double_matrix(Matrix_double* md) {
    if(md ->cols==0 || md->rows==0) return;
    for (int i = 0; i < md->rows; i++) {
        for (int j = 0; j < md->cols; j++) {
            printf("%lf ", md->data[i][j]);
        }
        printf("\n");
    }
    printf("\n");
} 

// Delete all matrixs data (no freed matrixs memory)
void manager_delete_all_matrixs(void) {
    Manager* manager = manager_instance();
    for (int i = 0; i < manager->num; i++) {
        //free data
        clear_matrix(manager->matrixs[i]);
    }
    manager->num = 0;
}

// Delete a matrix in the manager
void manager_delete_matrix(Matrix *m){
    Manager* manager = manager_instance();
    for (int i = 0; i < manager->num; i++) {
        if (manager->matrixs[i] == m) {
            clear_matrix(manager->matrixs[i]);
            manager->num--;
            // Shift the remaining matrixs to the left
            for (int j = i; j < manager->num; j++) {
                manager->matrixs[j] = manager->matrixs[j + 1];
            }
        }
    }
    manager->all_num--;
}
    


void manager_delete_matrix_float(Matrix_float *mf){
    Manager* manager = manager_instance();
    for (int i = 0; i < manager->num_float; i++) {
        if (manager->matrixs_float[i] == mf) {
            clear_float_matrix(manager->matrixs_float[i]);
            manager->num_float--;
            // Shift the remaining matrixs to the left
            for (int j = i; j < manager->num_float; j++) {
                manager->matrixs_float[j] = manager->matrixs_float[j + 1];
            }
        }
    }
    manager->all_num--;
}

void manager_delete_matrix_double(Matrix_double *md){
    Manager* manager = manager_instance();
    for (int i = 0; i < manager->num_double; i++) {
        if (manager->matrixs_double[i] == md) {
            clear_double_matrix(manager->matrixs_double[i]);
            manager->num_double--;
            // Shift the remaining matrixs to the left
            for (int j = i; j < manager->num_double; j++) {
                manager->matrixs_double[j] = manager->matrixs_double[j + 1];
            }
        }
    }
    manager->all_num--;
}

// Destruct the manager,Frees all memory in the manager
void destruct_manager(void) {
    Manager* manager = manager_instance();

    if (manager == NULL) {
        return;
    }
    //free all data
    for (int i = 0; i < manager->num; i++) {
        clear_matrix(manager->matrixs[i]);
    }
    free(manager->matrixs);
    
    for (int i = 0; i < manager->num_float; i++) {
        clear_float_matrix(manager->matrixs_float[i]);
    }
    free(manager->matrixs_float);

    for (int i = 0; i < manager->num_double; i++) {
        clear_double_matrix(manager->matrixs_double[i]);
    }
    free(manager->matrixs_double);
    
    free(manager);
    MANAGER_INSTANCE = NULL;
    printf("Destruct manager...\n");
}